﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.ServiceModel;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using MbUnit.Framework;
using Quail.BinaryCompressedPackageFile;
using QuailDashboardUnitTests.QuailDataServiceReference;
using QuailDashboardUnitTests.QuailTestRunnerServiceReference;


namespace QuailDashboardUnitTests
{
    [TestFixture]
    public class ServiceTests
    {
        [Test]
        public void GetTestPackages()
        {
            var service = CreateTestRunnerClient();
            var files = service.GetBinaryPackageFiles("AllTests", "QAA");

            Assert.GreaterThan(files.Length, 0, "Expecting 1 or more files");
        }

        /// <summary>
        /// Uploads a bunch of files, then downloads them and makes sure they're still the same
        /// </summary>
        [Test]
        public void TestBinaryPackages()
        {
            var service = CreateTestRunnerClient();
            var binaryfiles = BinaryCompressedPackageFile.GetAllFiles(@"E:\SAJPrimary\branches\release_7.5\QualityAssurance\QuailProject\Lib", "*.dll", "*.xml");

            // var str = service.GetCurrentUser();
            var packagename = "TestPackage";
            var version = "1.3";
            var packageid = service.CreateBinaryPackage(packagename, version);
            binaryfiles.ForEach(bcpf => service.AddBinaryPackageFile(packageid, bcpf));
            service.FinalizeBinaryPackage(packageid);

            var arrfiles = service.GetBinaryPackageFiles(packagename, version);

            var listfiles = new List<BinaryCompressedPackageFile>();
            listfiles.AddRange(arrfiles);

            var eq = new BinaryCompressedPackageFile.Equality();

            var c = binaryfiles.Except(listfiles, eq).Count();
            Assert.AreEqual(0, c, "Number of missing files");

            c = listfiles.Except(binaryfiles, eq).Count();
            Assert.AreEqual(0, c, "Number of extra files");
        }

        /// <summary>
        /// Verifies the raw file is the same as the decompressed file
        /// </summary>
        [Test]
        public void TestBinaryCompressedPackageFile()
        {
            var filename = @"D:\SAJTests\QAA\Lib\SAJDbEntities.dll";
            var rawfile = new MemoryStream();
            var hashalgo = SHA256.Create();
            using (var file = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                var data = new byte[2048];
                var read = file.Read(data, 0, 2048);
                while (read > 0)
                {
                    hashalgo.TransformBlock(data, 0, read, data, 0);
                    rawfile.Write(data, 0, read);
                    read = file.Read(data, 0, 2048);
                }

                hashalgo.TransformFinalBlock(data, 0, 0);
            }

            var determinedhash = Convert.ToBase64String(hashalgo.Hash);

            var comp = new BinaryCompressedPackageFile(filename);
            var hash = comp.Hash;
            Assert.AreEqual(determinedhash, hash, "Hash value");
            var orig = rawfile.ToArray();
            var uncomp = comp.GetUncompressed();

            Assert.AreEqual(orig, uncomp, "Original binary data");
        }

        [Test]
        public void TestGetTestRunTask()
        {
            var c = CreateDataClient();
            var tasks = c.GetTestRunTask(1310853, 1072303964);
        }

        /// <summary>
        /// Creates a new instance of the QuailDataServiceClient
        /// </summary>
        /// <returns>A new QuailDataServiceClient</returns>
        private static QuailDataServiceClient CreateDataClient()
        {
            var binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
            binding.ReaderQuotas.MaxArrayLength = 20000000; // use a large array so the xml deserializer doesn't choke
            var endpoint = new EndpointAddress("http://localhost:56605/QuailDataService.svc");
            binding.MaxReceivedMessageSize = 2147483647;
            binding.MaxBufferSize = 2147483647;

            var result = new QuailDataServiceClient(binding, endpoint);

            return result;
        }

        /// <summary>
        /// Creates a new instance of the QuailDataServiceClient
        /// </summary>
        /// <returns>A new QuailDataServiceClient</returns>
        private static QuailTestRunnerClient CreateTestRunnerClient()
        {
            var binding = new BasicHttpBinding(BasicHttpSecurityMode.None)
            {
                // ReaderQuotas = { MaxArrayLength = 20000000 },
                SendTimeout = new TimeSpan(0, 10, 0),
                ReceiveTimeout = new TimeSpan(0, 10, 0),
                MaxReceivedMessageSize = 2147483647,
                MaxBufferSize = 2147483647,
                ReaderQuotas = new XmlDictionaryReaderQuotas
                                   {
                                       MaxArrayLength = 2147483647
                                   }
            };

            var endpoint = new EndpointAddress("http://localhost:56605/QuailTestRunner.svc");

            var result = new QuailTestRunnerClient(binding, endpoint);

            return result;
        }
    }
}
